#include "backup.h"

char *src_arr[1000000];
char *des_arr[1000000];
int G_SRC_INDEX = 0;
int G_DES_INDEX = 0;
int G_INDEX = 0;

pthread_mutex_t mutex;

int getFileSize(char* filename) 
{ 
    struct stat sta; 
    stat(filename,&sta); 
    int size=sta.st_size;  
    return size; 
}

void displayProgressbar(char* name, int total, int current) {
	double value = (current / (double)total) * 100;
	int index;
	char progress[1024] = {0};
	strcat(progress, "[");
	for(index = 0; index < value; index += 5){
		strcat(progress, "#");
	}
	strcat(progress, "]");
	printf("%s %s %.2lf%%\n", name, progress, value);
}

void copy_file(char *file_src, char *file_dest)
{
	FILE *fp1, *fp2;
	char buf[1024] = {0};
	char message[1024] = {0};
	int total = 0;
	int current = 0;
	int len;
	printf("src file: %s\n", file_src);
	printf("dst file: %s\n", file_dest);
	fp1 = fopen(file_src, "r+");
	fp2 = fopen(file_dest, "aw+");
	if (NULL == fp1)
	{
		printf("fp1 error\n");
		exit(EXIT_FAILURE);
	}
	if (NULL == fp2)
	{
		printf("fp2 error\n");
		exit(EXIT_FAILURE);
	}

	total = getFileSize(file_src);

	while (1)
	{
		if (len = fread(buf, 1, sizeof(buf), fp1))
		{
			fwrite(buf, 1, len, fp2);
			current += len;
			displayProgressbar(file_src, total, current);
		}
		else
			break;
	}
	sprintf(message, "echo '复制文件 %s 到 %s 路径下' >>log.txt", file_src, file_dest); //写入log文件
	system(message);
	fclose(fp1);
	fclose(fp2);
}

void copy_dir(char *src, char *dest)
{
	DIR *srcdir = opendir(src);
	if (NULL == srcdir)
	{
		printf("open dir %s error, pls check it.\n", src);
		exit(EXIT_FAILURE);
	}
	struct dirent *entry = NULL;
	//存放子目录
	char path1[PATH_MAX] = {0};
	char path2[PATH_MAX] = {0};

	while (1)
	{
		entry = readdir(srcdir);
		if (entry == NULL)
			break;
		if (strcmp(".", entry->d_name) == 0 ||
			strcmp("..", entry->d_name) == 0)
			continue;
		sprintf(path1, "%s/%s", src, entry->d_name);
		sprintf(path2, "%s/%s", dest, entry->d_name);
		if (entry->d_type == DT_DIR)
		{
			char s[1024] = {0};
			sprintf(s, "echo '在 %s 目录下 新建目录 %s ' >>log.txt", dest, entry->d_name); //写入log文件
			system(s);
			mkdir(path2, S_IRUSR | S_IWUSR | S_IXUSR); //新建目录
			copy_dir(path1, path2);
		}
		else
		{
			src_arr[G_SRC_INDEX] = (char *)malloc(PATH_MAX);
			strcpy(src_arr[G_SRC_INDEX++], path1);
			des_arr[G_DES_INDEX] = (char *)malloc(PATH_MAX);
			strcpy(des_arr[G_DES_INDEX++], path2);
		}
	}
	closedir(srcdir);
}

void *run()
{
	while (1)
	{
		int index = -1;
		if (pthread_mutex_lock(&mutex) != 0)
		{
			printf("lock error\n");
			pthread_exit(NULL);
		}

		if (G_INDEX < G_DES_INDEX)
		{
			index = G_INDEX++;	
		}

		pthread_mutex_unlock(&mutex);

		if(index == -1) break;

		copy_file(src_arr[index], des_arr[index]);
		printf("thread: %lu\n", pthread_self());
		printf("当前进度： [%d/%d]\n", index, G_DES_INDEX);
	}
	pthread_exit(NULL);
}

void backup(char *src, char *dest)
{
	system("echo '------文件备份' >> log.txt");
	copy_dir(src, dest);
	pthread_mutex_init(&mutex, NULL);
	pthread_t threads[NUM_OF_THREADS];
	for (int j = 0; j < NUM_OF_THREADS; j++)
	{
		pthread_create(&threads[j], NULL, run, NULL);
	}
	for (int j = 0; j < NUM_OF_THREADS; j++)
	{
		pthread_join(threads[j], NULL);
	}
}

